home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / wstype / source / dropdm.c < prev    next >
C/C++ Source or Header  |  1991-10-18  |  4KB  |  174 lines

  1. /***   [dropdm.c]
  2. *
  3. *    ドロップダウンメニュー 関連        (C)ささがわ
  4. *
  5. *    For GNU C Compiler (GCC)   Version 1.39
  6. *
  7. ***/
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "dropdm.h"
  12. #include "graph.h"
  13. #include "mos.h"
  14. #include "others.h"
  15.  
  16. extern int    PAL_Black, PAL_Button;
  17. static int    Title, nTitle, nMenu, Shadow;
  18. static int    Yt1, Yt2, Xm1, Xm2, Ym1, Ym2;
  19. static struct menu_t    *Menu;
  20.  
  21. static int    DRPDM_sub(int *);
  22. static void    Rev_sub(int);
  23. static void    Open(void);
  24. static void    Close(void);
  25. static int    Where(int, int, int *);
  26. static int    Where_title(int, int);
  27.  
  28. /**
  29. *    ドロップダウンメニュー 関数
  30. *        入力:    x, y 呼び出し直前のマウス座標, dp パラメータ
  31. *        出力:    戻り値が真の場合 メニューが選択されたことを示す
  32. *                x タイトル番号, y メニュー番号 (戻り値が偽の場合は不定)
  33. **/
  34.  
  35. int DRPDM_main(int *x, int *y, struct dropdm_t *dp) {
  36.     int        t, p, mx, my;
  37.     char    mb;
  38.     
  39.     nTitle = dp->ntitle;    Yt1 = dp->yt1;
  40.     Yt2 = dp->yt2;    Ym1 = dp->ym;
  41.     Menu = dp->m;    Shadow = dp->shadow;
  42.     
  43.     if ((t = Where_title(*x, *y)) < 0)
  44.         return 0;
  45.     
  46.     do    p = t;    while (!DRPDM_sub(&t));
  47.     while (MOS_rdpos(&mb, &mx, &my), mb & 1);
  48.     *x = p;    *y = t;
  49.     
  50.     return (t < 0 ? 0 : 1);
  51. }
  52.  
  53. /*    入力:    t タイトル番号
  54.     出力:    戻り値が正の場合 メニューが選択され t にその番号が返される
  55.               〃    零の場合 タイトルが選択され t に    〃
  56.               〃    負の場合 上記以外が選択されたことを示す t は負
  57. */
  58.  
  59. static int DRPDM_sub(int *t) {
  60.     int        flag = -1, lop = 1;
  61.     int        mx, my, rel, fwh, wh;
  62.     char    mb;
  63.     
  64.     Title = *t;
  65.     for (nMenu = 0; Menu[Title].name[nMenu] != NULL; nMenu++);
  66.     Xm1 = Menu[Title].xm;
  67.     Xm2 = Xm1 + Menu[Title].wm * 8 - 1;
  68.     Ym2 = Ym1 + nMenu * 20 - 1;
  69.     
  70.     Open();
  71.     MOS_rdpos(&mb, &mx, &my);
  72.     rel = mb & 1 ? 0 : 1;
  73.     do {
  74.         int        a;
  75.         
  76.         do {
  77.             CLOCK(0);
  78.             MOS_rdpos(&mb, &mx, &my);
  79.         } while (!(mb & 1) && rel);
  80.         
  81.         fwh = Where(mx, my, &wh);
  82.         a = fwh > 0 && wh >= 0 ? wh : -1;
  83.         if (flag != a) {
  84.             Rev_sub(flag);    Rev_sub(a);
  85.             flag = a;
  86.         }
  87.         
  88.         if (mb & 1) {
  89.             if (rel && fwh < 0 || !fwh)
  90.                 lop = 0;
  91.             
  92.             rel = 0;
  93.         } else {
  94.             if (fwh <= 0 || wh >= 0)    /* !(fwh > 0 && wh < 0) */
  95.                 lop = 0;
  96.             
  97.             rel = 1;
  98.         }
  99.     } while (lop);
  100.     Close();
  101.     
  102.     *t = !fwh ? wh : flag;
  103.     return fwh;
  104. }
  105.  
  106. static void Rev_sub(int i) {
  107.     int        a;
  108.     
  109.     if (i < 0)
  110.         return;
  111.     
  112.     a = Ym1 + 20 * i;
  113.     EGB_rev(1, Xm1, a, Xm2, a + 19);
  114. }
  115.  
  116. static void Open(void) {
  117.     int        i;
  118.     struct menu_t    *p = Menu + Title;
  119.     
  120.     MOS_disp(0);
  121.     EGB_rev(0, p->xt, Yt1, p->xt + p->wt - 1, Yt2);
  122.     EGB_mycopy(EGB_readactPage(), Xm1 - 1, Ym1 - 1, Xm2 + 3, Ym2 + 3, 0, 650, 0);
  123.     if (Shadow) {
  124.         EGB_boxf(Xm2 + 2, Ym1 + 1, Xm2 + 3, Ym2 + 3, PAL_Black, PAL_Black);
  125.         EGB_boxf(Xm1 + 1, Ym2 + 2, Xm2 + 3, Ym2 + 3, PAL_Black, PAL_Black);
  126.     }
  127.     EGB_boxf(Xm1 - 1, Ym1 - 1, Xm2 + 1, Ym2 + 1, PAL_Black, 15);
  128.     for (i = 0; i < nMenu; i++)
  129.         EGB_str2(p->name[i], Xm1, Ym1 + i * 20 + 17, p->mask[i] ? PAL_Button : PAL_Black);
  130.     MOS_disp(1);
  131. }
  132.  
  133. static void Close(void) {
  134.     MOS_disp(0);
  135.     EGB_mycopy(0, 650, 0, 650 + Xm2 - Xm1 + 4, Ym2 - Ym1 + 4, EGB_readactPage(), Xm1 - 1, Ym1 - 1);
  136.     EGB_rev(0, Menu[Title].xt, Yt1, Menu[Title].xt + Menu[Title].wt - 1, Yt2);
  137.     MOS_disp(1);
  138. }
  139.  
  140. static int Where(int x, int y, int *wh) {
  141.     int        i, ret = -1;
  142.     
  143.     if (Xm1 <= x && x <= Xm2 && Ym1 <= y && y <= Ym2) {
  144.         struct menu_t    *p;
  145.         
  146.         *wh = (y - Ym1) / 20;
  147.         p = Menu + Title;
  148.         if (!strncmp(p->name[*wh] + 1, "─", 2) || p->mask[*wh]) *wh = -1;
  149.         ret = 1;
  150.     } else if ((i = Where_title(x, y)) >= 0) {
  151.         if (i == Title) {
  152.             *wh = -1;    ret = 1;
  153.         } else {
  154.             *wh = i;    ret = 0;
  155.         }
  156.     }
  157.     
  158.     return ret;
  159. }
  160.  
  161. static int Where_title(int x, int y) {
  162.     int        i, ret = -1;
  163.     struct menu_t    *p;
  164.     
  165.     for (i = 0, p = Menu; i < nTitle; i++, p++) {
  166.         if (p->xt <= x && x <= p->xt + p->wt - 1 && Yt1 <= y && y <= Yt2) {
  167.             ret = i;
  168.             break;
  169.         }
  170.     }
  171.     
  172.     return ret;
  173. }
  174.